package com.bjc.activiti.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bjc.activiti.bean.request.DeployFlowReqVO;
import com.bjc.activiti.bean.request.MyTaskReqVO;
import com.bjc.activiti.bean.response.ApproveRecordVO;
import com.bjc.activiti.bean.response.BackStepVO;
import com.bjc.activiti.bean.response.DeployFlowVO;
import com.bjc.activiti.bean.response.MyTaskVO;
import com.bjc.activiti.dao.IActivitiDao;
import com.bjc.activiti.service.IActivitiService;

/**
 * activiti serviceimpl
 *
 * @author 陈皓
 * @date 2017年11月13日
 */
@Service
public class ActivitiServiceImpl implements IActivitiService {
	@Autowired
	private TaskService taskService;
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private RuntimeService runtimeService;
	@Autowired
	private IdentityService identityService;
	@Autowired
	private IActivitiDao activitiDao;
	@Autowired
	private HistoryService historyService;
	@Override
	public boolean deployFlow(String flowName, String bpmnName) {
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
				.processDefinitionKey(bpmnName)
				.processDefinitionName(flowName).list();
		if (list.size() > 0) {
			return false;
		}
		repositoryService// 与流程定义和部署对象相关的Service
				.createDeployment() // 创建一个部署对象
				.name(flowName)// 添加部署的名称
				.addClasspathResource("processes/" + bpmnName + ".bpmn")// 从classpath的资源中加载，一次只能加载一个文件
				.addClasspathResource("processes/" + bpmnName + ".png")// 从classpath的资源中加载，一次只能加载一个文件
				.deploy(); // 完成部署
		return true;
	}
	
	/**
	 * 删除流程
	 */
	public void deleteDeployment() {
		String deploymentId = "87501";
		// 有未处理流程，删除异常
		repositoryService.deleteDeployment(deploymentId);
		// 删除流程全部信息：包括历史信息
		repositoryService.deleteDeployment(deploymentId, true);
	}

	@Override
	public List<MyTaskVO> getWaitDoTask(MyTaskReqVO myTaskReqVO) {
		List<MyTaskVO> list = activitiDao.getWaitDoTask(myTaskReqVO);
		return list;
	}
	
	@Override
	public List<MyTaskVO> getAlreadyDoTask(MyTaskReqVO myTaskReqVO) {
		List<MyTaskVO> list = activitiDao.getAlreadyDoTask(myTaskReqVO);
		return list;
	}
	
	@Override
	public String sendFlow(String flowKey,String businessId,Map<String, Object> variables) {
		Task task = taskService.createTaskQuery().processInstanceBusinessKey(businessId)
				.processDefinitionKey(flowKey).singleResult();
		if(task == null){
			identityService.setAuthenticatedUserId(variables.get("applyUser").toString());
			runtimeService.startProcessInstanceByKey(flowKey, businessId, variables);
		}else{
			taskService.addComment(task.getId(), task.getProcessInstanceId(), "送批", "");
			taskService.complete(task.getId(),variables); 
		}
		return "1";
	}
	
	@Override
	public String passFlow(String instanceId,String taskId,String comment) {
		Map<String, Object> variables = new HashMap<>();
		variables.put("nextStep", null);
		taskService.addComment(taskId, instanceId, "通过", comment);
		taskService.complete(taskId,variables);
		List<Task> taskList = taskService.createTaskQuery().processInstanceId(instanceId).list();
		if (taskList.size() == 0) { 
			return "2";
		} else {
			return "1";
		}
	}
	
	@Override
	public List<ApproveRecordVO> getApproveRecord(String instanceId) {
		List<ApproveRecordVO> list = activitiDao.getApproveRecord(instanceId);
		return list;
	}

	@Override
	public String overFlow(String instanceId,String taskId) {
		taskService.addComment(taskId, instanceId, "终止", "");
		runtimeService.deleteProcessInstance(instanceId, "终止");
		return "-1";
	}

	@Override
	public List<BackStepVO> getBackStep(String instanceId) {
		List<Task> taskList = taskService.createTaskQuery().processInstanceId(instanceId).list();
		List<BackStepVO> resultList = new ArrayList<>();
		ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(taskList.get(0).getProcessDefinitionId());
		List<ActivityImpl> activitiList = def.getActivities();
		for (ActivityImpl activityImpl : activitiList) {
			Object object = activityImpl.getProperty("taskDefinition");
			if(object != null){
				TaskDefinition taskDefinition = (TaskDefinition)object;
				if(taskDefinition.getNameExpression().toString().equals("填写审批单")){
					BackStepVO backStepVO = new BackStepVO();
					backStepVO.setStepId(taskDefinition.getKey());
					backStepVO.setStepName(taskDefinition.getNameExpression().toString());
					resultList.add(backStepVO);
					break;
				}
			}
		}
		List<BackStepVO> list = activitiDao.getBackStep(instanceId, taskList.get(0).getTaskDefinitionKey());
		for (BackStepVO backStepVO : list) {
			resultList.add(backStepVO);
		}
		return resultList;
	}
	
	@Override
	public String backFlow(String instanceId,String taskId,String nextStep,String comment) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("nextStep", nextStep);
		taskService.addComment(taskId, instanceId, "驳回", comment);
		taskService.complete(taskId, variables);
		List<Task> taskList = taskService.createTaskQuery().processInstanceId(instanceId).list();
		if(taskList.get(0).getName().equals("填写审批单")){
			return "3";
		}else{
			return "1";
		}
	}
	
	@Override
	public void transferApprove(String taskId, String toUser) {
		taskService.setAssignee(taskId, toUser);
	}

	@Override
	public List<DeployFlowVO> getDeployFlow(DeployFlowReqVO deployFlowReqVO) {
		return activitiDao.getDeployFlow(deployFlowReqVO);
	}

	@Override
	public String getInstanceId(String flowKey, String businessId) {
		List<HistoricTaskInstance> list = historyService
				.createHistoricTaskInstanceQuery()
				.processInstanceBusinessKey(businessId)
				.processDefinitionKey(flowKey)
				.list();
		if(list.size() >0){
			return list.get(0).getProcessInstanceId();
		}else{
			return "";
		}
	}
	
	@Override
	public void suspendFlow(String instanceId){
        runtimeService.suspendProcessInstanceById(instanceId);
    }

	@Override
	public void activateFlow(String instanceId) {
		runtimeService.activateProcessInstanceById(instanceId);
	}
}
